/*
 * Copyright 2023-2025, Haiku, Inc. All rights reserved.
 * Distributed under the terms of the MIT License.
 *
 * Authors:
 *   Haiku Development Team
 */

#include "arch_timer.h"

#include <KernelExport.h>

#include <kernel.h>
#include <safemode.h>
#include <boot/stage2.h>
#include <boot/menu.h>
#include <arch_cpu_defs.h>

#include <string.h>

//#define TRACE_TIMER
#ifdef TRACE_TIMER
#	define TRACE(x) dprintf x
#else
#	define TRACE(x) ;
#endif

// LoongArch64定时器相关寄存器操作
static inline uint64_t
read_csr(uint32_t reg)
{
	uint64_t value;
	asm volatile("csrrd %0, %1" : "=r"(value) : "i"(reg));
	return value;
}

static inline void
write_csr(uint32_t reg, uint64_t value)
{
	asm volatile("csrwr %0, %1" : : "r"(value), "i"(reg));
}

// 获取当前计数器值
static uint64_t
get_timer_count(void)
{
	return read_csr(CSR_TVAL);
}

// 设置定时器配置
static void
set_timer_config(uint64_t value)
{
	write_csr(CSR_TCFG, value);
}

// 清除定时器中断
static void
clear_timer_interrupt(void)
{
	write_csr(CSR_TICLR, 1);
}

// 初始化架构定时器
void
arch_timer_init(void)
{
	// 获取定时器频率
	// 在LoongArch64中，定时器频率通常是处理器频率的一部分
	// 这里我们假设一个默认值，实际应该从设备树或ACPI表中获取
	const uint64_t timerFrequency = 25000000; // 25MHz，典型值

	// 存储定时器频率到内核参数
	gKernelArgs.arch_args.timerFrequency = timerFrequency;

	// 初始化定时器配置
	// 禁用定时器中断，设置为连续模式
	set_timer_config(0);

	// 清除任何挂起的定时器中断
	clear_timer_interrupt();

	TRACE(("LoongArch64定时器初始化完成，频率: %lld Hz\n", timerFrequency));
}

// 获取当前时间戳（微秒）
bigtime_t
arch_get_time_stamp(void)
{
	// 从计数器获取当前值并转换为微秒
	uint64_t ticks = get_timer_count();
	uint64_t frequency = gKernelArgs.arch_args.timerFrequency;

	// 转换为微秒 (ticks * 1000000 / frequency)
	return (bigtime_t)((ticks * 1000000ULL) / frequency);
}